﻿using System;

namespace Chip8.Core.Processor.Operations
{
	internal class ADDv : Operation
	{
		public ADDv(int registerIndex, byte value)
		{
			RegisterIndex = registerIndex;
			Value = value;
		}

		public int RegisterIndex { get; set; }

		public byte Value { get; set; }

		public override void Execute(ICPU cpu)
		{
			var result = cpu.V[RegisterIndex] + Value;
			unchecked
			{
				cpu.V[RegisterIndex] = (byte)result;
			}
		}
	}

	internal class ADDr : Operation
	{
		public ADDr(int targetRegisterIndex, int sourceRegisterIndex)
		{
			SourceRegisterIndex = sourceRegisterIndex;
			TargetRegisterIndex = targetRegisterIndex;
		}

		public int SourceRegisterIndex { get; set; }

		public int TargetRegisterIndex { get; set; }

		public override void Execute(ICPU cpu)
		{
			var result = cpu.V[SourceRegisterIndex] + cpu.V[TargetRegisterIndex];
			cpu.Carry = result >= 0x100 ? (byte)1 : (byte)0;
			unchecked
			{
				cpu.V[TargetRegisterIndex] = (byte)result;
			}
		}
	}

	internal class ADDi : Operation
	{
		public ADDi(int sourceRegisterIndex)
		{
			SourceRegisterIndex = sourceRegisterIndex;
		}

		public int SourceRegisterIndex { get; set; }

		public override void Execute(ICPU cpu)
		{
			var result = cpu.I + cpu.V[SourceRegisterIndex];
			unchecked
			{
				cpu.I = (ushort)result;
			}
		}
	}
}
